package com.swf.common.fmt;

import java.io.*;
import java.util.*;
import java.util.regex.*;

import org.dom4j.*;

import com.swf.common.base.*;
import com.swf.common.utils.*;
import com.swf.common.xml.*;

public class FmtXmlUtil {
	public static final String xmlEncoderRegex = "<\\?xml version=\"((?:\\d|\\.)+)\" encoding=\"((?:\\w|\\-)+)\"\\?>[\\s\\S]*?(?:(?=<))" ;
	public static final String fmtDefRegex = "<fmtDef id=\"(gw\\d{4})ReceiveFormat\">([\\s\\S]+?)</fmtDef>" ;

	/**
	 * 通过ReceiveFmt生成字符串报文
	 * @param fmt
	 * @return
	 * @throws DocumentException
	 * @throws IOException
	 */
	public static String createReceiveFormat(ReceiveFmt fmt)
			throws DocumentException, IOException {
		Document document = DocumentHelper.createDocument();
		XmlHead xmlHead = fmt.getXmlHead();
		XmlWrap xmlWrap = fmt.getXmlWrap();
		Element root = document.addElement(xmlWrap.getTagName());
		for (XmlFullTag xmlFullTag : xmlWrap.getXmlFullTagList()) {
			Element element = root.addElement(xmlFullTag.getTagName());
			element.setText(" ");
		}
		for (XmlIColl xmlIColl : xmlWrap.getXmlICollList()) {
			Element iColl = root.addElement(xmlIColl.getTagName());
			for (XmlWrap wrap : xmlIColl.getXmlWrapList()) {
				addXmlWrap(iColl, wrap);
			}
		}
		return FwsPatternUtils.replaceRegex(FwsXmlUtils.formatPrettyXml(root.asXML()),
				xmlEncoderRegex,
				"<?xml version=\"" + xmlHead.getVersion() + "\" encoding=\""
						+ xmlHead.getEncoding() + "\"\\?>"+FwsConstants.line_separator);
	}

	/**
	 * 循环添加xmlWrap到生成的返回报文中
	 * @param root
	 * @param xmlWrap
	 */
	public static void addXmlWrap(Element root, XmlWrap xmlWrap) {
		Element node = root.addElement(xmlWrap.getTagName());
		for (XmlFullTag xmlFullTag : xmlWrap.getXmlFullTagList()) {
			Element element = node.addElement(xmlFullTag.getTagName());
			element.setText(" ");
		}
		for (XmlIColl xmlIColl : xmlWrap.getXmlICollList()) {
			Element iColl = root.addElement(xmlIColl.getTagName());
			for (XmlWrap wrap : xmlIColl.getXmlWrapList()) {
				addXmlWrap(iColl, wrap);
			}
		}
	}


	/**
	 * 通过ReceiveFmt的内容content生成ReceiveFmt的所有信息
	 * @param fmt
	 * @return
	 * @throws DocumentException
	 */
	public static ReceiveFmt dealFmt(ReceiveFmt fmt) throws DocumentException {
		Document document = DocumentHelper.parseText(fmt.getContent());
		Element root = document.getRootElement();

		// get xmlHead
		Element xmlHeadNode = root.element("xmlHead");
		XmlHead xmlHead = new XmlHead();
		xmlHead.setVersion(xmlHeadNode.attributeValue("version"));
		xmlHead.setEncoding(xmlHeadNode.attributeValue("encoding"));
		fmt.setXmlHead(xmlHead);

		// get XmlWrap
		Element element = root.element("xmlWrap");
		XmlWrap xmlWrap = getXmlWrap(element);
		fmt.setXmlWrap(xmlWrap);
		return fmt;
	}

	/**
	 * 通过xml节点获取XmlWrap对象
	 * @param xmlWrapNode
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private static XmlWrap getXmlWrap(Element xmlWrapNode) {
		XmlWrap xmlWrap = new XmlWrap();
		xmlWrap.setTagName(xmlWrapNode.attributeValue("tagName"));
		List<XmlFullTag> xmlFullTagList = new ArrayList<XmlFullTag>();
		Iterator<Element> it = xmlWrapNode.elementIterator("xmlFullTag");
		while (it.hasNext()) {
			Element xmlFullTagNode = (Element) it.next();
			XmlFullTag xmlFullTag = new XmlFullTag();
			xmlFullTag.setDataName(xmlFullTagNode.attributeValue("dataName"));
			xmlFullTag.setTagName(xmlFullTagNode.attributeValue("tagName"));
			xmlFullTagList.add(xmlFullTag);
		}
		xmlWrap.setXmlFullTagList(xmlFullTagList);

		List<XmlIColl> xmlICollList = new ArrayList<XmlIColl>();
		Iterator<Element> ite = xmlWrapNode.elementIterator("xmlIColl");
		while (ite.hasNext()) {
			Element xmlICollNode = ite.next();
			XmlIColl xmlIColl = new XmlIColl();
			xmlIColl.setDataName(xmlICollNode.attributeValue("dataName"));
			xmlIColl.setTagName(xmlICollNode.attributeValue("tagName"));
			Iterator<Element> iter = xmlICollNode.elementIterator("xmlWrap");
			while (iter.hasNext()) {
				Element xmlWrapNode2 = iter.next();
				XmlWrap xmlWrap2 = getXmlWrap(xmlWrapNode2);
				xmlIColl.addXmlWrap(xmlWrap2);
			}
			xmlICollList.add(xmlIColl);
		}
		xmlWrap.setXmlICollList(xmlICollList);
		return xmlWrap;
	}
}
